#ifndef __FSMAISTATE_H__
#define __FSMAISTATE_H__

#include "FsmAIDef.h"

class FsmAI;
class EventParam;

class FsmAIState {
public:
    FsmAIState() {};
    virtual ~FsmAIState() {};
    virtual FSM_AI_STATE getType() = 0;
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) = 0;
    virtual void enter(FsmAI* ai) = 0;
    virtual void leave(FsmAI* ai) = 0;
    virtual void pulse(FsmAI* ai, UINT tm) = 0;
protected:
    
};

class FsmAIStateIdle : public FsmAIState {
public:
    FsmAIStateIdle() {};
    virtual ~FsmAIStateIdle() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_IDLE;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param);
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};


class FsmAIStateChase : public FsmAIState  {
public:
    FsmAIStateChase() {};
    virtual ~FsmAIStateChase() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_CHASE;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStateAttack : public FsmAIState  {
public:
    FsmAIStateAttack() {};
    virtual ~FsmAIStateAttack() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_ATTACK;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStateBack : public FsmAIState  {
public:
    FsmAIStateBack() {};
    virtual ~FsmAIStateBack() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_BACK;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStateFlee : public FsmAIState  {
public:
    FsmAIStateFlee() {};
    virtual ~FsmAIStateFlee() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_FLEE;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStateDisperse : public FsmAIState  {
public:
    FsmAIStateDisperse() {};
    virtual ~FsmAIStateDisperse() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_DISPERSE;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStateTeamFollow : public FsmAIState  {
public:
    FsmAIStateTeamFollow() {};
    virtual ~FsmAIStateTeamFollow() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_TEAM_FOLLOW;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStatePlayAct : public FsmAIState  {
public:
    FsmAIStatePlayAct() {};
    virtual ~FsmAIStatePlayAct() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_PLAY_ACT;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};


class FsmAIStateScaring : public FsmAIState  {
public:
    FsmAIStateScaring() {};
    virtual ~FsmAIStateScaring() {};
    virtual FSM_AI_STATE getType() {return FSM_AI_STATE::AI_SCARING;};
    virtual void onEvent(FsmAI* ai, FSM_AI_EVENT event, EventParam* param) {};
    virtual void enter(FsmAI* ai);
    virtual void leave(FsmAI* ai);
    virtual void pulse(FsmAI* ai, UINT tm);
};

class FsmAIStateCache{
public:
    static FsmAIState* getState(FSM_AI_STATE state) {
        static FsmAIStateIdle m_idle;
        static FsmAIStateAttack m_attack;
        static FsmAIStateBack m_back;
        static FsmAIStateChase m_chase;
        static FsmAIStateDisperse m_disperse;
        static FsmAIStateFlee m_flee;
        static FsmAIStatePlayAct m_playact;
        static FsmAIStateScaring m_scaring;
        static FsmAIStateTeamFollow m_teamfollow;
        FsmAIState* ret = 0;
        switch (state)
        {
        case FSM_AI_STATE::AI_IDLE:
            ret = &m_idle;
            break;
        case FSM_AI_STATE::AI_ATTACK:
            ret = &m_attack;
            break;
        case FSM_AI_STATE::AI_BACK:
            ret = &m_back;
            break;
        case FSM_AI_STATE::AI_CHASE:
            ret = &m_chase;
            break;
        case FSM_AI_STATE::AI_DISPERSE:
            ret = &m_disperse;
            break;
        case FSM_AI_STATE::AI_FLEE:
            ret = &m_flee;
            break;
        case FSM_AI_STATE::AI_PLAY_ACT:
            ret = &m_playact;
            break;
        case FSM_AI_STATE::AI_SCARING:
            ret = &m_scaring;
            break;
        case FSM_AI_STATE::AI_TEAM_FOLLOW:
            ret = &m_teamfollow;
            break;
        default:
            ret = &m_idle;
            break;
        }
        return ret;
    }
private:
    
};
#endif